package Persistance;

import org.apache.log4j.Logger;

import java.util.*;

public class SortedList<Key,Value> implements Map<Key,Value>{

    private static Logger logger = Logger.getLogger("MovieSystem.Persistance.SortedList");

    TreeMap<Key, LinkedList<Value>> m_map;

    public SortedList(){
        m_map = new TreeMap<Key, LinkedList<Value>>();
    }

    public int size() {
        int res = 0;
        for (LinkedList<Value> l : m_map.values())
            res += l.size();
        return res;
    }

    public boolean isEmpty() {
        for (LinkedList<Value> l : m_map.values())
            if (!l.isEmpty())
                return false;
        return true;
    }

    public boolean containsKey(Object key) {
        return m_map.containsKey(key);            
    }

    @SuppressWarnings({"SuspiciousMethodCalls"})
    public boolean containsValue(Object value) {
        for (LinkedList<Value> l : m_map.values())
            if (l.contains(value))
                return true;
        return false;
    }

    public Value get(Object key) {
        if (!m_map.get(key).isEmpty())
            return m_map.get(key).getFirst();
        else
            return null;
    }

    public Value put(Key key, Value value) {
        if (!containsKey(key))
            m_map.put(key,new LinkedList<Value>());
        m_map.get(key).add(value);
        return value;
    }

    @SuppressWarnings({"SuspiciousMethodCalls"})
    public Value remove(Object key) {
        Value res = m_map.get(key).remove();
        if (m_map.get(key).isEmpty())
            m_map.remove(key);
        return res;
    }

    public void putAll(Map<? extends Key, ? extends Value> m) {
        for (Entry<? extends Key, ? extends Value> e : m.entrySet())
            put(e.getKey(),e.getValue());
    }

    public void clear() {
        m_map.clear();
    }

    public Set<Key> keySet() {
        return m_map.keySet();
    }

    public Collection<Value> values() {
        LinkedList<Value> res = new LinkedList<Value>();
        for (LinkedList<Value> l : m_map.values())
            res.addAll(l);
        return res;
    }

    public Set<Entry<Key, Value>> desendingEntrySet() {

        logger.info("Sorted list size is "+size());
        LinkedHashSet<Entry<Key, Value>> res = new LinkedHashSet<Entry<Key,Value>>();
        for (Entry<Key, LinkedList<Value>> e : m_map.descendingMap().entrySet()){
            for (Value l : e.getValue()){
                TreeMap<Key,Value> tmp = new TreeMap<Key,Value>();
                tmp.put(e.getKey(),l);
                res.add(tmp.firstEntry());
            }
        }
        logger.error("EntrySet size is "+res.size());
        return res;
    }

    public Set<Entry<Key, Value>> entrySet() {

        logger.info("Sorted list size is "+size());
        LinkedHashSet<Entry<Key, Value>> res = new LinkedHashSet<Entry<Key,Value>>();
        for (Entry<Key, LinkedList<Value>> e : m_map.entrySet()){
            for (Value l : e.getValue()){
                TreeMap<Key,Value> tmp = new TreeMap<Key,Value>();
                tmp.put(e.getKey(),l);
                res.add(tmp.firstEntry());
            }
        }
        logger.error("EntrySet size is "+res.size());
        return res;
    }
}
